import asyncio
import aiohttp
import ujson
from traceback import print_exc
import aiofiles
import os.path as path
from time import time, strftime, localtime
import datetime
import pytz
# 调度器
from apscheduler.schedulers.background import BackgroundScheduler
# from apscheduler.schedulers.asyncio import AsyncIOScheduler

# 设置调度器
# scheduler = AsyncIOScheduler()
scheduler = BackgroundScheduler()

# 时区按UTC-0的来，算了，改成转为当前时区

baseUrl = "https://api.warframestat.us/pc/"
# basePath = "D:\\QQ_BOT\\cqhttp\\bot"  # 这个文件所在的目录
basePath = path.split(path.realpath(__file__))[0]  # 这个文件所在的目录
print("base Path = ", basePath)
# 这个文件所在的目录

debug = 1

# 用于配置jobid，初始为1
jobId = 1
jobIdList = [""]

# wf的数据
parsed_full_dict = dict()
parsed_nightwave = dict()  # 午夜电波
parsed_sale_dict = dict()  # 买卖
parsed_invasion = dict()   # 入侵

# 保存的对象
CambionDrift = dict()  # 火卫二的
CambionDriftCount = 0  # 函数被运行的次数
CetusCycle = dict()  # 希图斯
CetusCycleCount = 0
Sotie = dict()  # 每日突击
SotieStr = ""  # 每日突击的描述，便于直接取来用，因为每日突击不用在输出时计算还剩多少时间
Fissures = dict()
Arbitration = dict()
Invasions = list()  # 入侵
InvasionsStr = ""
SentientOutposts = dict()  # s佬的飞船
VoidTrader = dict()  # 虚空商人、奸商
VallisCycle = dict()  # 奥布山谷、金星平原

# 帮助字符串
help_str = "当前可用功能（使用时不用加双引号，双引号只是为了让人看着方便）: \n1.火卫二平原现状，命令：火卫二\n 2.地球平原现状，命令：“地球平原”或“地球”或“希图斯”或“平原时间”\n"\
           + "3.金星平原现状，命令：“金星平原”或“奥布山谷”或“金星”\n4.查看每日突击，命令: “每日突击”或“突击”\n"\
           + "5.查看虚空裂隙，命令：裂隙\n6.查看仲裁任务，命令：仲裁\n7.查看虚空商人信息，命令：“虚空商人”或“奸商”\n"\
           + "7.查看入侵任务，命令：“入侵”\n8.翻译，命令：“翻译 需要翻译的中文或英文”\n9.匿名留言，命令：“留言 要留言的内容”\n"\
           + "更多功能正在开发中，尽情期待~\n若需反馈意见和建议、请使用匿名留言功能，谢谢！"


def ceshi():
    t = scheduler.get_jobs()
    my_str = "["
    for i in t:
        my_str += "<Job name=" + i.name + ", next_run:" + str(i.next_run_time) + ">\n"
    my_str += "]"
    # return str(scheduler.get_jobs())
    return my_str


@scheduler.scheduled_job('interval', minutes=2, name="jobMonitor")
def jobMonitor():
    if debug:
        print(strftime("%Y-%m-%d %H:%M:%S", localtime(time())), ", 运行jobMonitor():")
    try:
        # 事件id字典，isActive用于判断是否正在激活
        ids = {
            "CambionDrift": False,
            "CetusCycle": False,
            "Sotie": False,
            "Fissures": False,
            "Arbitration": False,
            "Invasions": False,
            "SentientOutposts": False,
            "VoidTrader": False,
            "VallisCycle": False,
            "jobMonitor": True
        }
        # 获取事件循环，并遍历
        jobs = scheduler.get_jobs()
        for i in jobs:
            ids[i.name] = True
        # 遍历job完成后，查找仍为false的项
        for key in ids:
            # 若对应的项为false，则运行对应的函数
            if not ids[key]:
                key = "update" + key
                # await eval(key)()
                doFunc(globals()[key])
                if debug:
                    print("缺少，已启动", key)
    except:
        print_exc()
    finally:
        if debug:
            print("jobMonitor()运行完毕")

def getHelp():
    return help_str


'''
转换时间
将str类型的时间转换为当地时间的datetime带时区对象，当前是返回中国时间
mystr: String，如2021-03-16T14:13:25.481
'''
def transformTime(mystr):
    utc = pytz.timezone('UTC')
    tz_china = pytz.timezone('Asia/Shanghai')

    utctime = datetime.datetime.fromisoformat(mystr)
    china_time = utctime.replace(tzinfo=utc).astimezone(tz=tz_china)
    return china_time


# 接受一个datetime的带时区对象，返回剩余的时间
# 计算剩余时间，将秒转换为x天x小时x分x秒这种
# 一分60秒
# 一小时 3600 秒
# 一天 86400 秒
def parseLeftTime(mytime, isDatetimeObject=True):
    if mytime is None:
        return ""
    nowtime = datetime.datetime.now().astimezone()  # 当前时间
    timediff = mytime - nowtime  # 时间差对象
    mytime = timediff.seconds  # 得到的是秒，类型是int
    mydays = timediff.days  # 天数

    mytime = mytime % 86400
    myhours = mytime // 3600  # 小时数
    mytime = mytime % 3600
    myminutes = mytime // 60  # 分钟数
    mytime = (mytime % 60) or None  # 剩下的就是秒数了
    mystr = ""
    if mydays != 0:
        mystr += str(mydays) + "天"
    if myhours != 0:
        mystr += str(myhours) + "小时"
    if myminutes != 0:
        mystr += str(myminutes) + "分"
    if mytime != 0:
        mystr += str(mytime) + "秒"
    return mystr


def doFunc(myfunc):
    loop = None
    runFlag = 0
    # 如果没有事件循环，就创建一个
    try:
        loop = asyncio.get_event_loop()
        runFlag = 1
    except:
        loop = asyncio.new_event_loop()
    a = loop.create_task(myfunc())
    if not runFlag:
        loop.run_until_complete(a)


# 留言功能
def comment(text):
    try:
        my_time = strftime("%Y-%m-%d %H:%M:%S", localtime(time()))
        with open("comment.txt", "a") as f:
            f.write(my_time + ":\n" + text + "\n")
        return "已收到留言"
    except:
        return "留言失败，出错，请直接@我"


'''
翻译
:param str mytype: 需要翻译的单词的种类
:param str text: 需要翻译的单词或句子
return None或对应的翻译
'''
def translate(text, mytype = 'default'):
    # res = ""
    try:
        if mytype == "default":
            return parsed_full_dict.get(text.lower())
        if mytype == "node":  # 翻译任务节点,如： Ganalen's Grave (Veil Proxima)
            text = text.strip()
            t = text.index("(")
            return text[:t-1] + "(" + parsed_full_dict.get(text[t+1:-1].lower()) + ")"  # Ganalen's Grave(面纱比邻星)
        elif mytype == "invasion":  # 翻译入侵的奖励
            return str(parsed_invasion.get(text.strip().lower()))
    except:
        print_exc()
        return ""

# 警报，但是现状好像是没有了
async def updateAlertsData_no():
    pass


# 加载词典
async def dictLoad():
    try:
        global parsed_full_dict, parsed_nightwave, parsed_sale_dict, parsed_invasion, basePath
        floderPath = 'WFA_Lexicon-WFA5' # json文件存放的文件夹
        async with aiofiles.open(path.join(basePath, floderPath, 'WF_Dict.json'),encoding='UTF-8', mode='r') as f:
            contents = await f.read()
            t = ujson.loads(contents)  
            d = dict()
            for i in t:  # {"id":1773,"zh":"环境灾害","en":"Environmental Hazard"}
                d[i["en"].lower()] = i["zh"]
                d[i["zh"]] = i["en"]
            parsed_full_dict = d
        async with aiofiles.open(path.join(basePath, floderPath, 'WF_Sale.json'), encoding='UTF-8', mode='r') as f:
            contents = await f.read()
            parsed_sale_dict = ujson.loads(contents)
        async with aiofiles.open(path.join(basePath, floderPath, 'WF_NightWave.json'), encoding='UTF-8', mode='r') as f:
            contents = await f.read()
            parsed_nightwave = ujson.loads(contents)
        async with aiofiles.open(path.join(basePath, floderPath, 'WF_Invasion.json'), encoding='UTF-8', mode='r') as f:
            contents = await f.read()
            t = ujson.loads(contents)
            d = dict()
            for i in t:
                d[i["en"].lower()] = i["zh"]
                d[i["zh"]] = i["en"]
            parsed_invasion = d
            # parsed_invasion = ujson.loads(contents)
        if debug:
            print("设置完成！")
        return True
    except:
        if debug:
            print("dict_updater()出错")
        print_exc()
        return False

'''
魔胎之境现状、火卫二
拿到之后首先放到一个字典里，保存现状的状态和结束时间，然后根据结束时间设置job
{
    "id": "cambionCycle1614828780000",
    "activation": "2021-03-04T01:53:00.000Z",
    "expiry": "2021-03-04T03:33:00.000Z",
    "active": "fass"
}
'''
async def updateCambionDrift():
    global debug, CambionDriftCount
    if debug:
        print(strftime("%Y-%m-%d %H:%M:%S", localtime(time())), ", 运行updateCambionDrift():")
    async with aiohttp.request("GET", baseUrl + "cambionCycle") as f:
        a = ujson.loads(await f.text())
        if a:
            if debug:
                print("updateCambionDrift函数，得到a: ")
                print(a)
            parseCambionDriftStatus(a)
        else:
            if debug:
                print("updateCambionDrift函数，未得到a")
            return "ERROR in updateCambionDrift()"


def parseCambionDriftStatus(myjson):
    global CambionDrift, scheduler
    try:
        endtime = transformTime(myjson["expiry"][:-1])
        CambionDrift["status"] = myjson["active"]
        CambionDrift["end"] = endtime  # 保存datetime对象
    except:
        print_exc()
        endtime = datetime.datetime.now().astimezone() - datetime.timedelta(minutes=1)
    a = scheduler.add_job(doFunc, 'date', max_instances=10, run_date=endtime + datetime.timedelta(minutes=2),
                          name="CambionDrift", args=[updateCambionDrift])
    if debug:
        print("parseCambionDriftStatus()添加任务: ", a)
    if not scheduler.running:
        scheduler.start()
    if debug:
        print("parseCambionDriftStatus()执行完毕后, jobs= ", scheduler.get_jobs())


def readCambionDriftStatus():
    global CambionDrift
    # 计算剩余时间
    # timenow = datetime.datetime.now().astimezone()
    # res_time = (CambionDrift["end"] - timenow).seconds  # 得到的是秒，类型是int
    if debug:
        print("开始返回数据")
    # mystr = "当前: "+ CambionDrift["status"] + ", 剩余: " + str(parseLeftTime(res_time)) + "\n"
    mystr = "当前: " + CambionDrift["status"] + ", 剩余: " + str(parseLeftTime(CambionDrift["end"])) + "\n"
    if debug:
        print("构造的数据是,", mystr)
    return "当前: "+ CambionDrift["status"] + ", 剩余: " + str(parseLeftTime(CambionDrift["end"])) + "\n"

'''
希图斯现状、地球平原
{
"id": "cetusCycle1614828780000",
"expiry": "2021-03-04T03:33:00.000Z",
"activation": "2021-03-04T01:53:00.000Z",
"isDay": true,
"state": "day",
"timeLeft": "1h 30m 41s",
"isCetus": true,
"shortString": "1h 30m to Night"
}
'''


async def updateCetusCycle():
    if debug:
        print(strftime("%Y-%m-%d %H:%M:%S", localtime(time())), ", 运行updateCetusCycle():")
    async with aiohttp.request("GET", baseUrl + "cetusCycle?language=en") as f:
        a = ujson.loads(await f.text())
        if a:
            if debug:
                print("updateCetusCycle函数，得到a: ")
                print(a)
            parseCetusCycle(a)
        else:
            if debug:
                print("updateCetusCycle函数，未得到a")
            return "ERROR in updateCetusCycle()"


def parseCetusCycle(myjson):
    global CetusCycle, scheduler
    try:
        endtime = transformTime(myjson["expiry"][:-1])
        CetusCycle["status"] = myjson["state"]
        CetusCycle["end"] = endtime  # # 保存datetime对象
    except:
        print_exc()
        endtime = datetime.datetime.now().astimezone()
    # 添加任务，使用当前时区
    a = scheduler.add_job(doFunc, 'date', max_instances=10, name="CetusCycle",
                      run_date=endtime + datetime.timedelta(minutes=30), args=[updateCetusCycle])
    if debug:
        print("parseCetusCycle()添加任务: ", a)
    if not scheduler.running:
        scheduler.start()


def readCetusCycle():
    global CetusCycle
    # 计算剩余时间
    if debug:
        print("readCetusCycle()开始返回数据")
    # s = {
    #     "day":"白天",
    #     ""
    # }
    s = ""
    if CetusCycle["status"] == "day":
        s = "白天"
    else:
        s = "夜晚"
    mystr = "当前: " + s + ", 剩余: " + str(parseLeftTime(CetusCycle["end"])) + "\n"
    if debug:
        print("readCetusCycle()构造的数据是,", mystr)
    return "当前: " + s + ", 剩余: " + str(parseLeftTime(CetusCycle["end"])) + "\n"

'''
武形秘仪
暂时不用
'''
async def updateConclaveChallenges_no():
    async with aiohttp.request("GET", baseUrl + "conclaveChallenges") as f:
        return await ujson.loads(f.text())

'''
每日突击
{
"id": "603fbd0d26df963cbc5924c3",
"activation": "2021-03-03T17:00:00.000Z",
"startString": "-20h 28m 21s",
"expiry": "2021-03-04T17:00:00.000Z",
"active": true,
"rewardPool": "Sortie Rewards",
"variants": [
{
"boss": "Deprecated",
"planet": "Deprecated",
"missionType": "Hive",
"modifier": "Enemy Physical Enhancement: Impact", 或"Augmented Enemy Armor"
"modifierDescription": "Enemies can deal enhanced impact damage. Finishing damage is not resisted.",
"node": "Solium (Eris)"
},
{
"boss": "Deprecated",
"planet": "Deprecated",
"missionType": "Mobile Defense",
"modifier": "Weapon Restriction: Melee Only",
"modifierDescription": "Only melee weapons may be used in this mission, any other weapon type is not allowed, and will be removed automatically if equipped.",
"node": "Palus (Pluto)"
},
{
"boss": "Deprecated",
"planet": "Deprecated",
"missionType": "Spy",
"modifier": "Environmental Hazard: Dense Fog",
"modifierDescription": "Limited visibility in the tileset due to dense fog. Forced night cycle on planets like earth.",
"node": "Cervantes (Earth)"
}
],
"boss": "Mutalist Alad V",
"faction": "Infestation",
"expired": false,
"eta": "3h 31m 38s"
}
'''
async def updateSotie():
    if debug:
        print(strftime("%Y-%m-%d %H:%M:%S", localtime(time())), ", 运行updateSotie():")
    async with aiohttp.request("GET", baseUrl + "sortie?language=en") as f:
        a = ujson.loads(await f.text())
        if a:
            if debug:
                print("updateSotie函数，得到a: ")
                print(a)
            parseSotie(a)
        else:
            if debug:
                print("updateSotie函数，未得到a")
            return "ERROR in updateSotie()"


def parseSotie(myjson):
    global Sotie, SotieStr
    try:  # 如果出错，只能是请求到的数据有问题
        mystr = ''
        endtime = transformTime(myjson["expiry"][:-1])
        Sotie["boss"] = myjson["boss"]
        mystr += "Boss: " + myjson["boss"] + "\n"
        Sotie["faction"] = myjson["faction"]
        mystr += "派系: " + myjson["faction"] + "\n"
        t = list()  # 用于存放解析后的任务列表
        if myjson["variants"]:
            mystr += "任务列表：\n"
            for i in myjson["variants"]:
                # 任务类型
                missionType = translate(i.get("missionType"))
                mystr += "任务类型：" + missionType + "\n"
                m = i.get("modifier")  # 临时变量，保存当前任务的敌人强化
                modifier = ""
                if m:
                    s = m.split(":")  # ["Weapon Restriction"," Melee Only"]
                    if m.find(":") != -1:  # 存在:，则代表s中有两个元素
                        modifier += translate(s[0]) + ": " + translate(s[1].strip())
                        mystr += "特殊: " + modifier + "\n"
                    else:
                        modifier += translate(s[0])
                        mystr += "特殊: " + modifier + "\n"
                # 节点
                node_t = i.get("node")  # 临时变量，保存英文节点信息，如"V Prime (Venus)"
                ss = ''
                if node_t:
                    index_t = node_t.find("(")
                    if index_t:
                        try:
                            node = node_t[:index_t-1] + "(" + translate(node_t[index_t+1:-1]) + ")"
                        except:
                            node = str(node_t)
                    else:
                        node = str(node_t)
                else:
                    node = "None"
                mystr += "节点: " + node + "\n"

                t.append({
                    "missionType": missionType,
                    # "modifier": ''.join(translate(tt.strip()) for tt in s),
                    "modifier": modifier,
                    "node": node
                })
        Sotie["variants"] = t
        SotieStr = mystr
        if debug:
            print("总的突击str = ", mystr)
    except:
        print_exc()
        endtime = datetime.datetime.now().astimezone()
    a = scheduler.add_job(doFunc, 'date', max_instances=10, run_date=endtime + datetime.timedelta(minutes=3),
                      name="Sotie", args=[updateSotie])
    if debug:
        print("parseSotie()添加任务: ", a)
    if not scheduler.running:
        scheduler.start()


def readSotie():
    return SotieStr
    

'''
遗物
好像还有一个可以search的功能

'''
async def updateRiven_no():
    async with aiohttp.request("GET", baseUrl + "rivens?language=zh") as f:
        return await ujson.loads(f.text())
        pass


'''
现在的裂隙

fissures.json
'''
async def updateFissures():
    if debug:
        print(strftime("%Y-%m-%d %H:%M:%S", localtime(time())), ", 运行updateFissures():")
    async with aiohttp.request("GET", baseUrl + "fissures?language=en") as f:
        a = ujson.loads(await f.text())
        if a:
            if debug:
                print("updateFissures函数，得到a: ")
                print(a)
            parseFissures(a)
        else:
            if debug:
                print("updateFissures函数，未得到a")
            return "ERROR in updateFissures()"


def parseFissures(myjson):
    global Fissures, scheduler
    try:
        detail_debug = 1
        tDict = {
            "Lith": list(),  # 古纪
            "Meso": list(),  # 前纪
            "Neo": list(),  # 中纪
            "Axi": list(),  # 后纪
            "Requiem": list()  # 安魂
        }
        # 当前时间，用于和遍历中的时间进行比对，以确定下次执行的时间
        dtnow = datetime.datetime.now().astimezone()
        dt_flag = 0  # 如果已经从列表中取到了第一个时间，则将flag置0，以后只进行比对
        if debug:
            print("in parseFissures(), dtnow = ", dtnow)
        # 挨个遍历原数据，判断时间、翻译，并放到字典中
        for i in myjson:
            if i.get("active"):  # 如果该节点被激活，则解析，否则不解析
                d = dict()
                # 当前节点的结束时间
                t = transformTime(i["expiry"][:-1])
                if detail_debug:
                    print("parseFissures(), 当前节点: ", i)
                    print("当前节点解析得到的时间为: ", t)
                d["expiry"] = t
                if dt_flag == 0:  # 如果flag等于0，则将当前的时间保存为flag
                    dtnow = t
                    dt_flag = 1
                    if detail_debug:
                        print("当前flag = 0, 保存节点时间，新的dtnow为: ", dtnow)
                # 如果flag等于1，则比对该元素的时间与dt_now的大小，若dt_now更大，则将dt_now改为t，使dt_now改为t，以此得到所有元素中最小的时间
                else:
                    if dtnow > t:
                        dtnow = t
                        if detail_debug:
                            print("当前的dtnow大于当前节点时间, 保存当前节点时间， 新dtnow为: ", dtnow)
                # 任务节点
                d["node"] = translate(i["node"], "node")
                # 任务类型
                d["missionType"] = translate(i["missionType"])
                # 派系
                d["enemy"] = i["enemy"]
                # 存放数据
                a = i["tier"]
                tDict[a].append(d)
        # 添加任务，使用当前时区
        Fissures.clear()
        Fissures = tDict
        if debug:
            print("parseFissures()函数解析出的数据为: ", tDict)
    except:
        print_exc()
        dtnow = datetime.datetime.now().astimezone()
    a = scheduler.add_job(doFunc, 'date', name="Fissures", max_instances=10,
                          run_date=dtnow + datetime.timedelta(minutes=2), args=[updateFissures])
    if debug:
        print("parseFissures()添加任务: ", a)
    if not scheduler.running:
        scheduler.start()

'''
可查询指定类型的裂隙
'''
def readFissures(mytype=None):
    global Fissures
    mystr = ''
    
    def pinjie(mydata):
        a = parseLeftTime(mydata["expiry"])
        return "剩余: " + a + "\n节点: " + mydata["node"] + "\n任务类型: " + mydata["missionType"] + "\n派系: " \
               + mydata["enemy"] + "\n"
    # 默认返回全部
    for i in Fissures.keys():
        mystr += "--" + translate(i) + "--:\n"
        for j in Fissures[i]:  # 这里才是具体的对象
            mystr += pinjie(j)
    if debug:
        print("解析裂隙的函数中，最后得到的是：\n", mystr)
    return mystr

'''
赤毒
无
'''
async def updateKuvaMission_no():
    async with aiohttp.request("GET", baseUrl + "kuva?language=zh") as f:
        return await ujson.loads(f.text())
        pass

'''
仲裁
{
"activation": "2021-03-04T02:05:00.000Z",
"expiry": "2021-03-04T03:04:00.000Z",
"enemy": "Orokin",
"type": "防禦",
"archwing": false,
"sharkwing": false,
"node": "Taranis (虚空)"
}
'''
async def updateArbitration():
    if debug:
        print(strftime("%Y-%m-%d %H:%M:%S", localtime(time())), ", 运行updateArbitration():")
    try:
        async with aiohttp.request("GET", baseUrl + "arbitration?language=en") as f:
            a = ujson.loads(await f.text())
            if a:
                if debug:
                    print("updateArbitration函数，得到a: ")
                    print(a)
                parseArbitration(a)
            else:
                if debug:
                    print("updateArbitration函数，未得到a")
                e = datetime.datetime.now().astimezone()
                scheduler.add_job(doFunc, 'date', name="Arbitration", max_instances=10,
                                  run_date=e + datetime.timedelta(seconds=30), args=[updateArbitration])
                if not scheduler.running:
                    scheduler.start()
                return "ERROR in updateArbitration()"
    except:
        print_exc()
        e = datetime.datetime.now().astimezone()
        scheduler.add_job(doFunc, 'date', name="Arbitration", max_instances=10,
                          run_date=e + datetime.timedelta(seconds=20), args=[updateArbitration])
        if not scheduler.running:
            scheduler.start()

    # if not a:  # 没有获取到数据
    #     return None
    # else:
    #     parseArbitration(a)


def parseArbitration(myjson):
    global Arbitration, scheduler
    try:
        # 当前时间，用于和遍历中的时间进行比对，以确定下次执行的时间
        endtime = transformTime(myjson["expiry"][:-1])
        Arbitration["expiry"] = endtime  # 结束时间
        Arbitration["type"] = translate(myjson.get("type"))  # 任务种类
        Arbitration["enemy"] = myjson.get("enemy")  # 敌人派系，该API不稳定，不一定又enemy，所以用get
        Arbitration["node"] = translate(myjson.get("node"), "node")
    except:
        print_exc()
        endtime = datetime.datetime.now().astimezone()
    a = scheduler.add_job(doFunc, 'date', name="Arbitration", max_instances=10,
                      run_date=endtime + datetime.timedelta(seconds=30), args=[updateArbitration])
    if debug:
        print("parseArbitration()添加任务: ", a)
    if not scheduler.running:
        scheduler.start()


def readArbitration():
    try:
        # 计算剩余时间
        t = parseLeftTime(Arbitration.get("expiry"))
        mystr = '任务: ' + Arbitration["type"] + "\n节点: " + Arbitration["node"] + "\n派系: " \
                + Arbitration["enemy"] + "\n剩余: " + t
        if debug:
            print("解析仲裁的函数中，最后得到的是：\n", mystr)
        return mystr
    except:
        return "出错（该接口不稳定）"

'''
入侵

invasions.json
'''
async def updateInvasions():
    if debug:
        print(strftime("%Y-%m-%d %H:%M:%S", localtime(time())), ", 运行updateInvasions():")
    async with aiohttp.request("GET", baseUrl + "invasions?language=en") as f:
        a = ujson.loads(await f.text())
        if a:
            if debug:
                print("updateInvasions函数，得到a: ")
                print(a)
            parseInvasions(a)
        else:
            if debug:
                print("updateInvasions函数，未得到a")
            return "ERROR in updateInvasions()"


def parseInvasions(myjson):
    global Invasions, InvasionsStr, scheduler
    try:

        nowtime = datetime.datetime.now().astimezone()  # 每小时请求一次
        if debug:
            print("begin parseInvasions()), Invasions is: ")
            print(Invasions)
            print("begin parseInvasions")
        Invasions.clear()
        for i in myjson:
            t = dict()
            t["node"] = translate(i["node"], "node") or None  # 节点
            t["attacker"] = i["attackingFaction"] or None  # 进攻方

            t["defender"] = i["defendingFaction"] or None  # 防守方
            r = dict()  # 暂存防守方奖励
            r["count"] = i["defenderReward"]["countedItems"][0]["count"] or None
            r["item"] = translate(i["defenderReward"]["countedItems"][0]["key"], "invasion") or None
            t["defenderReward"] = r or None  # 防守奖励

            tt = i["vsInfestation"]  # 是否是i系进攻
            t["vsInfestation"] = tt
            if not tt:  # 如果不是i系进攻
                r["count"] = i["attackerReward"]["countedItems"][0]["count"] or None
                r["item"] = translate(i["attackerReward"]["countedItems"][0]["key"], "invasion") or None
                t["attackerReward"] = r or None  # 攻击奖励
            t["completion"] = i["completion"] or None  # 进度，浮点数
            t["completed"] = i["completed"]  # 是否已完成，boolean
            if debug:
                print("finish this, t = ", t)
            Invasions.append(t)
        if debug:
            print("Invasions = ")
            print(Invasions)

        # 生成入侵字符串
        mystr = '---入侵--- \n'
        for i in Invasions:
            # 星球、防御、防御奖励、进度
            if not i["completed"]:  # 只显示未完成的
                mystr += '节点: ' + i["node"] + "\n"
                if i["vsInfestation"]:
                    mystr += "进攻方: Infestation\n"
                else:
                    mystr += '进攻方: ' + i["attacker"] + "\n协助进攻奖励: " + str(i["attackerReward"]["count"]) + "x" \
                             + i["attackerReward"]["item"] + "\n"
                mystr += '防守方: ' + str(i["defender"]) + "\n协助防守奖励: " + str(i["defenderReward"]["count"]) + "x" \
                         + str(i["defenderReward"]["item"]) + "\n"
                mystr += "进度: " + "%.2f" % (100 - i["completion"]) + "%\n\n"
        if debug:
            print("解析入侵的功能中，最后得到的是：\n", mystr)
        InvasionsStr = mystr
        # 添加定时器，一小时后启动
        scheduler.add_job(doFunc, 'date', name="Invasions", max_instances=10, run_date=nowtime + datetime.timedelta(
                        hours=1),
                        args=[updateInvasions])
        if not scheduler.running:
            scheduler.start()
    except:
        # 若失败，30秒后执行
        print_exc()
        nowtime = datetime.datetime.now().astimezone
        a = scheduler.add_job(doFunc, 'date', max_instances=10, run_date=nowtime + datetime.timedelta(seconds=30),
                          name="Invasions", args=[updateInvasions])
        if debug:
            print("parseInvasions()添加任务: ", a)
    if not scheduler.running:
        scheduler.start()
   

def readInvasions():
    global InvasionsStr
    if debug:
        print("readInvasions()开始返回数据")
    return InvasionsStr


'''
s佬出现(飞船)
激活时是下面这样的：
{
"mission": {
"node": "Ganalen's Grave (Veil Proxima)",
"faction": "Grineer",
"type": "Skirmish"
},
"activation": "2021-03-07T10:38:04.000Z",
"expiry": "2021-03-07T11:08:04.000Z",
"active": true,
"id": "CrewBattleNode551:true"
}
'''


async def updateSentientOutposts():
    if debug:
        print(strftime("%Y-%m-%d %H:%M:%S", localtime(time())), ", 运行updateSentientOutposts():")
    async with aiohttp.request("GET", baseUrl + "sentientOutposts?language=en") as f:
        a = ujson.loads(await f.text())
        if a:
            if debug:
                print("updateSentientOutposts函数，得到a: ")
                print(a)
            parseSentientOutposts(a)
        else:
            if debug:
                print("updateSentientOutposts函数，未得到a")
            return "ERROR in updateSentientOutposts()"


def parseSentientOutposts(myjson):
    global SentientOutposts, scheduler
    try:
        endtime = transformTime(myjson["expiry"][:-1])  # 结束时间
        t = dict()
        t["expiry"] = endtime
        t["active"] = myjson["active"]
        t["type"] = translate(myjson["mission"]["type"])
        t["node"] = translate(myjson["mission"]["node"], "node")
    except:
        print_exc()
        endtime = datetime.datetime.now().astimezone()
    # 添加定时器，一分钟后启动
    a = scheduler.add_job(doFunc, 'date', name="SentientOutposts", max_instances=10, run_date=endtime + datetime.timedelta(
                        minutes=3),
                      args=[updateSentientOutposts])
    if debug:
        print("parseSentientOutposts()添加任务: ", a)
    if not scheduler.running:
        scheduler.start()

def readSentientOutposts():
    global SentientOutposts
    mystr = ''
    if SentientOutposts["active"]:  # 已激活
        mystr += "节点: " + SentientOutposts["node"] + "\n任务类型: " + SentientOutposts["type"] \
                + "剩余: " + parseLeftTime(SentientOutposts["expiry"]) + "\n"
    else:
        return "当前无s佬飞船事件"
    if debug:
        print("解析s佬飞船的函数中，最后得到的是：\n", mystr)
    return mystr


'''
虚空商人、奸商
{
"id": "5d1e07a0a38e4a4fdd7cefca",
"activation": "2021-03-12T14:00:00.000Z", 下一次开始的时间
"startString": "8d 11h 32m 39s", 下一次结束的时间
"expiry": "2021-03-14T14:00:00.000Z",
"active": false,
"character": "Baro Ki'Teer",
"location": "Strata 中继站 (地球)",
"inventory": [],
"psId": "5d1e07a0a38e4a4fdd7cefca0",
"endString": "10d 11h 32m 39s"
}
'''
async def updateVoidTrader():
    if debug:
        print(strftime("%Y-%m-%d %H:%M:%S", localtime(time())), ", 运行updateVoidTrader():")
    try:
        async with aiohttp.request("GET", baseUrl + "voidTrader?language=zh") as f:
            a = ujson.loads(await f.text())
            if a:
                print("updateVoidTrader函数，得到a: ")
                print(a)
                parseVoidTrader(a)
            else:
                print("updateVoidTrader函数，未得到a")
                return "ERROR in updateVoidTrader()"
    except:
        print_exc()
        e = datetime.datetime.now().astimezone()
        scheduler.add_job(doFunc, 'date', name="VoidTrader", max_instances=10,
                          run_date=e + datetime.timedelta(seconds=50), args=[updateVoidTrader])
        if not scheduler.running:
            scheduler.start()


def parseVoidTrader(myjson):
    global VoidTrader, scheduler

    try:
        endtime = transformTime(myjson["expiry"][:-1])  # 结束时间
        starttime = transformTime(myjson["activation"][:-1])  # 开始时间
        t = dict()
        t["expiry"] = endtime
        t["activation"] = starttime
        t["active"] = myjson["active"]
        # t["location"] = translate(myjson["node"], "node")
        t["location"] = myjson["location"]  # 使用zh自带的中文翻译、还是能用的
        if myjson["active"]:
            t_list = list()
            for i in myjson["inventory"]:
                t_dict = dict()
                t_dict["item"] = str(translate(i.get("item")) or i.get("item"))
                t_dict["ducats"] = str(i.get("ducats"))
                t_dict["credits"] = str(i.get("credits"))
                t_list.append(t_dict)
            t["inventory"] = t_list
        VoidTrader = t  # 赋值
        if debug:
            print("VoidTrader is ", VoidTrader)
    except:
        print_exc()
        endtime = datetime.datetime.now().astimezone()

    # 添加定时器，一分钟后启动
    a = scheduler.add_job(doFunc, 'date', name="VoidTrader", max_instances=10, run_date=endtime + datetime.timedelta(
                        minutes=1),
                      args=[updateVoidTrader])
    if debug:
        print("parseVoidTrader()添加任务: ", a)
    if not scheduler.running:
        scheduler.start()


def readVoidTrader():
    global VoidTrader
    try:
        mystr = ''
        is_active = VoidTrader.get("active")

        if is_active:  # 虚空商人已到达
            inventory_str = ""
            for i in VoidTrader["inventory"]:
                inventory_str += i.get("item") + " " + i.get("ducats") + "奸商币 "\
                                 + i.get("credits") + "现金\n"
            mystr += "---虚空商人---\n已到达: " + VoidTrader["location"] + "\n距离离开还剩: " \
                     + parseLeftTime(VoidTrader["expiry"]) + "\n商品列表如下:\n" + inventory_str
        else:  # 虚空商人未到达
            mystr += "---虚空商人---\n" + "距到达 " + VoidTrader["location"] + " 还差: " \
                    + parseLeftTime(VoidTrader["activation"]) + "\n"
        if debug:
            print("解析虚空商人的函数中，最后得到的是：\n", mystr)
        return mystr
    except:
        print_exc()
        e = datetime.datetime.now().astimezone()
        scheduler.add_job(doFunc, 'date', name="VoidTrader", max_instances=10,
                          run_date=e + datetime.timedelta(seconds=30), args=[updateVoidTrader])
        if not scheduler.running:
            scheduler.start()
        return "出错，正在重试，请20秒后再次尝试"


'''
集团任务
syndicateMissions.json
'''
async def updateSyndicateMissions_no():
    async with aiohttp.request("GET", baseUrl + "syndicateMissions") as f:
        return await ujson.loads(f.text())
        pass

'''
奥布山谷、金星平原
{
"id": "vallisCycle1614825180000",
"expiry": "2021-03-04T02:53:48.000Z",
"isWarm": false,
"state": "cold",
"activation": "2021-03-04T02:33:00.000Z",
"timeLeft": "17m 27s",
"shortString": "17m to Warm"
}
'''
async def updateVallisCycle():
    if debug:
        print(strftime("%Y-%m-%d %H:%M:%S", localtime(time())), ", 运行updateVallisCycle():")
    try:
        async with aiohttp.request("GET", baseUrl + "vallisCycle") as f:
            a = ujson.loads(await f.text())
            if a:
                if debug:
                    print("updateVallisCycle函数，得到a: ")
                    print(a)
                parseVallisCycle(a)
            else:
                if debug:
                    print("updateVallisCycle函数，未得到a")
                return "ERROR in updateVallisCycle()"
    except:
        print_exc()
        e = datetime.datetime.now().astimezone()
        scheduler.add_job(doFunc, 'date', name="VallisCycle", max_instances=10,
                          run_date=e + datetime.timedelta(seconds=10), args=[updateVallisCycle])
        if not scheduler.running:
            scheduler.start()


def parseVallisCycle(myjson):
    global VallisCycle, scheduler
    try:
        endtime = transformTime(myjson["expiry"][:-1])
        t = dict()
        t["expiry"] = endtime
        t["isWarm"] = myjson["isWarm"]
        t["state"] = myjson["state"]
        VallisCycle = t
    except:
        print_exc()
        endtime = datetime.datetime.now().astimezone()
    # 添加任务，使用当前时区
    a = scheduler.add_job(doFunc, 'date', run_date=endtime + datetime.timedelta(minutes=1),
                      name="VallisCycle", max_instances=10, args=[updateVallisCycle])
    if debug:
        print("parseVallisCycle()添加任务: ", a)
    if not scheduler.running:
        scheduler.start()


def readVallisCycle():
    if debug:
        print("readVallisCycle()开始返回数据: ")
    try:
        mystr = ""
        mystr += "---金星平原---\n" + VallisCycle["state"] + "，剩余时间: " \
                 + parseLeftTime(VallisCycle["expiry"])
        if debug:
            print("构造的数据是,", mystr)
        return mystr
    except:
        return "出错，正在重试，请20秒后再试"
        print_exc()
        e = datetime.datetime.now().astimezone()
        scheduler.add_job(doFunc, 'date', name="VallisCycle", max_instances=10,
                          run_date=e + datetime.timedelta(seconds=10), args=[updateVallisCycle])
        if not scheduler.running:
            scheduler.start()


async def initUpdate():
    await updateCambionDrift()
    await updateCetusCycle()  # 希图斯
    await updateSotie()
    await updateFissures()  # 裂隙
    await updateArbitration()  # 仲裁，该接口不稳定
    await updateInvasions()
    await updateSentientOutposts()  # s船
    await updateVoidTrader()
    await updateVallisCycle()  # 金星平原

# 仲裁、突击、入侵都没有问题
# 有问题的： 地球平原、裂隙、s船、金星平原


# await updateCambionDrift()
# asyncio.run( updateCambionDrift() )
# doFunc(updateCambionDrift)
# loop = asyncio.get_event_loop()
# loop.create_task(updateCambionDrift())